package cn.hadron.aa.dao.impl;
import java.io.Serializable;
import java.util.List;
import java.lang.reflect.ParameterizedType;

import cn.hadron.aa.dao.*;
import cn.hadron.aa.entity.Article;
import cn.hadron.aa.util.Pager;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
//DAO父类，把通用的crud等代码放在BaseDao实现类中；然后子类继承后，只需要添加额外的实现。
public class BaseDaoImpl<T> implements BaseDao<T> {
	private Class<T> entity;
	//Spring3.1以后，不再支持HibernateTemplate,只能使用原生的session接口来操作
    @Autowired
    private SessionFactory sessionFactory;
   
    //含参构造器，初始化entity
    public BaseDaoImpl(Class<T> entityClass){
        this.entity = entityClass;
    }
    //单例模式获取Session
    protected Session getSession(){
    	return sessionFactory.getCurrentSession();
    }
    @Override
    public Serializable save(T entity) {
        return getSession().save(entity);
    }
    @Override
    public void delete(T entity) {
        getSession().delete(entity);
    }
    @Override
    public void delete(Serializable id) {
    	getSession().delete(this.get(id));
    }
    @Override
    public void update(T entity) {
        getSession().update(entity);
    }
    @Override
    public T get(Serializable id) {
        return (T) getSession().get(entity, id);
    }
    @Override
	public List<T> getAll() {
		return get("from "+entity.getSimpleName());
	}
	@Override
    public List<T> get(String hql) {
        return getSession().createQuery(hql).list();
    }
	@Override
    public Integer getCount() {
    	//SQL聚集函数count()、sum()等唯一返回值是Long型
    	String hql="select count(*) from "+entity.getSimpleName();
    	Number m=(Number)getSession().createQuery(hql).uniqueResult();
    	return m.intValue();
    }
    @Override
    @SuppressWarnings("unchecked")
    public List<T> get(String hql, Object... param) {
        Query query = getSession().createQuery(hql);
        if (param != null && param.length > 0) {
            for (int i = 0; i < param.length; i++) {
            	query.setParameter(i, param[i]);
            }
        }
        return query.list();
    }
    @Override
    public Pager<T> getPager(final int pageNo,final int pageSize){
    	getSession().clear();
    	final Pager<T> pager = new Pager<T>(pageNo, pageSize, this.getCount());
    	String hql="from "+entity.getSimpleName()+" order by id asc";
    	List<T> list =getSession().createQuery(hql,entity)
    	       .setFirstResult((pager.getPageNo()-1)*pageSize)
    	       .setMaxResults(pageSize)
    	       .list();
    	pager.setData(list);
		return pager;
    }
}
